package br.com.sistransporte.transite.linha.linhaponto.dao;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;

import org.hibernate.Query;
import org.hibernate.Session;

import br.com.sistransporte.transitevo.linha.model.LinhaPontoVO;
import br.com.src.masterpersistence.dao.GenericDAO;
import br.com.src.masterpersistence.exceptions.AlterarException;
import br.com.src.masterpersistence.exceptions.ExcluirException;
import br.com.src.masterpersistence.exceptions.FiltrarException;
import br.com.src.masterpersistence.exceptions.HibernatePersistenceException;
import br.com.src.masterpersistence.exceptions.InserirException;
import br.com.src.masterpersistence.utilidades.FabricaMensagensLog;
import br.com.src.masterpersistence.utilidades.Paginacao;
import br.com.src.utilidades.exceptions.DesconhecidoException;

public class LinhaPontoDAOImpl extends GenericDAO<LinhaPontoVO> implements LinhaPontoDAOService {

	public LinhaPontoDAOImpl(String typeSessionFactory) {
		super(typeSessionFactory);
		logger.info( FabricaMensagensLog.getMensagemLogConstrutor("LinhaPontoDAOImpl") );
	}

	
	public ArrayList<LinhaPontoVO> filtrar(LinhaPontoVO vo, boolean isDisticnt,boolean isLike) throws FiltrarException {
		logger.info( FabricaMensagensLog.getMensagemLogInicio("LinhaPontoDAOImpl") );
		try {
			ArrayList< LinhaPontoVO > lista = filter( vo, isDisticnt, isLike );
			logger.info( FabricaMensagensLog.getMensagemLogTermino( "LinhaPontoDAOImpl" ) );
			return lista;
		} catch ( IllegalArgumentException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro("LinhaPontoDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( IllegalAccessException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "LinhaPontoDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( InvocationTargetException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "LinhaPontoDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( Exception e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "LinhaPontoDAOImpl", new DesconhecidoException( e.getMessage(), e ) ) );
			throw new FiltrarException( e.getMessage(), e );
		}
	}

	public LinhaPontoVO inserir(LinhaPontoVO vo) throws InserirException {
		try {
			logger.info( FabricaMensagensLog.getMensagemLogInicio( "LinhaPontoDAOImpl" ) );
			LinhaPontoVO objetoPersistido = (LinhaPontoVO) insert( vo );
			logger.info( FabricaMensagensLog.getMensagemLogTermino( "LinhaPontoDAOImpl" ) );
			return objetoPersistido;
		} catch ( HibernatePersistenceException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "LinhaPontoDAOImpl", e ) );
			throw new InserirException( e.getMessage(), e );
		}
	}

	
	public void alterar(LinhaPontoVO vo) throws AlterarException {
		logger.info( FabricaMensagensLog.getMensagemLogInicio( "LinhaPontoDAOImpl" ) );
		try {
			update( vo );
		} catch ( HibernatePersistenceException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro("LinhaPontoDAOImpl", e ) );
			throw new AlterarException( e.getMessage(), e );
		}
		logger.info( FabricaMensagensLog.getMensagemLogTermino("LinhaPontoDAOImpl" ) );
	    
		
	}

	
	public void excluir(LinhaPontoVO vo) throws ExcluirException {
		logger.info( FabricaMensagensLog.getMensagemLogInicio( "LinhaPontoDAOImpl" ) );
		try {
			delete( vo );
		} catch ( HibernatePersistenceException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "LinhaPontoDAOImpl", e ) );
			throw new ExcluirException( e.getMessage(), e );
		}
		logger.info( FabricaMensagensLog.getMensagemLogTermino( "LinhaPontoDAOImpl" ) );
	}

	
	public ArrayList<LinhaPontoVO> filtrarPaginacao(Paginacao<LinhaPontoVO> pagination, LinhaPontoVO vo, boolean isDisticnt,	boolean isLike) throws FiltrarException {
		logger.info( FabricaMensagensLog.getMensagemLogInicio( "LinhaPontoDAOImpl" ) );
		try {
			ArrayList< LinhaPontoVO > lista = paginacao( pagination, vo, isDisticnt, isLike );
			logger.info( FabricaMensagensLog.getMensagemLogTermino( "LinhaPontoDAOImpl" ) );
			return lista;
		} catch ( IllegalArgumentException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "LinhaPontoDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( IllegalAccessException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "LinhaPontoDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( InvocationTargetException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "LinhaPontoDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( Exception e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "LinhaPontoDAOImpl", new DesconhecidoException( e.getMessage(), e ) ) );
			throw new FiltrarException( e.getMessage(), e );
		}
		
	}
	
	@SuppressWarnings( "unchecked" )
    public ArrayList<LinhaPontoVO> listarLinhaPontoPorLinha(Integer idLinha) throws FiltrarException {
		logger.info( FabricaMensagensLog.getMensagemLogInicio("PontoDAOImpl") );
		
		Session session = getSessaoAberta();
		try {

			Query query = session.createQuery("SELECT lp FROM LinhaPontoVO lp WHERE lp.linha.id = :idLinha");
			query.setInteger("idLinha", idLinha);
			
			ArrayList< LinhaPontoVO > listaLinhaPonto = (ArrayList< LinhaPontoVO >) query.list();
			
			return listaLinhaPonto;
		} catch ( IllegalArgumentException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro("PontoDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( Exception e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "PontoDAOImpl", new DesconhecidoException( e.getMessage(), e ) ) );
			throw new FiltrarException( e.getMessage(), e );
		} finally{
			session.close();
		}
	}
	
    public Integer obterUltimaOrdemParadaPorLinha(Integer idLinha) throws FiltrarException {
		logger.info( FabricaMensagensLog.getMensagemLogInicio("PontoDAOImpl") );
		Session session = getSessaoAberta();
		try {
			
			Query query = session.createQuery("SELECT MAX(lp.ordemParada) FROM LinhaPontoVO lp WHERE lp.linha.id = :idLinha");
			query.setInteger("idLinha", idLinha);
			
			return (Integer) query.uniqueResult();
		} catch ( IllegalArgumentException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro("PontoDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( Exception e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "PontoDAOImpl", new DesconhecidoException( e.getMessage(), e ) ) );
			throw new FiltrarException( e.getMessage(), e );
		} finally {
			session.close();
		}
	}
    
	@Override
    public Integer getTotalCadastrados( LinhaPontoVO entidade, boolean isDisticnt, boolean isLike ) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		return super.getTotalCadastrados( entidade, isDisticnt, isLike );
	    
    }

}
